package com.to8to.kitt.esb;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;

import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.to8to.kitt.utils.LogPatterns;
import com.to8to.kitt.utils.LogUtils;
import com.to8to.kitt.utils.NettyUtils;

public class SDFutureListener implements ChannelFutureListener{

	public static Logger logger = LoggerFactory.getLogger(SDFutureListener.class);  
	
	private BusMessageState status;
	
	private Entry<String, Channel> instanceChannel;
	
	private ZKServiceChannelPool serviceChannelPool;
	
	public SDFutureListener(Entry<String, Channel> instanceChannel, BusMessageState status, ZKServiceChannelPool serviceChannelPool)
	{
		this.instanceChannel = instanceChannel;
		this.status = status;
		this.serviceChannelPool = serviceChannelPool;
	}
	
	@Override
	public void operationComplete(ChannelFuture future)
			throws Exception {
		
		LogUtils.openTag(status.getTag());
		
		status.recordFinishSendDownTime();
		
		String head = status.inMsg.getHead().name;
		
		if(future.isSuccess())
		{	
			logger.debug(LogPatterns.SEND_TO_DOWN, future.channel().toString(), future.channel().remoteAddress().toString(), status.getOldseq(), status.getNewseq(), head);
		}
		else 
		{
			boolean isOpen = future.channel().isOpen();
			boolean isActive = future.channel().isActive();
			boolean isRegistered = future.channel().isRegistered();
			boolean isWritable = future.channel().isWritable();
			
			logger.error(LogPatterns.SEND_TO_DOWN_FAIL + "\n" + "isOpen: " + isOpen + ", isActive: " + isActive + ", isRegistered: " + isRegistered + ", isWritable: " + isWritable
					, future.channel().toString(), future.channel().remoteAddress().toString(), status.getOldseq(), status.getNewseq(), head);
			
			String dump = serviceChannelPool.dumpServiceConnectionsMT();
			
			logger.warn("下游服务的连接信息:\n" + dump);
			
			if(!(isOpen && isActive && isRegistered && isWritable))
			{
				boolean health = NettyUtils.checkChannelHealth(future.channel());
				if(!health)
				{
					logger.warn("############################################\n跟下游的连接有问题: {}, 重新连接!!\n###########################################", instanceChannel.toString());
					
					String service = status.meta.service;
					
					String instance = instanceChannel.getKey();
					
					serviceChannelPool.ensureCloseMT(service, instance);
				}
			}
		}
		
		status.inMsg.getBuff().release();
		
		LogUtils.removeTag();
		
		future.removeListener(this);
	}
}